import pluginJs from '@eslint/js'
import unocss from '@unocss/eslint-config/flat'
import importPlugin from 'eslint-plugin-import'
import jsdoc from 'eslint-plugin-jsdoc'
import perfectionist from 'eslint-plugin-perfectionist'
import prettier from 'eslint-plugin-prettier'
import unicorn from 'eslint-plugin-unicorn'
import unusedImports from 'eslint-plugin-unused-imports'
import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'
import tseslint from 'typescript-eslint'

import autoImportGlobals from './.eslintrc-auto-import.json'

export default [
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  // ...pluginVue.configs['flat/essential'], // Vue 基础规则
  // ...pluginVue.configs['flat/recommended'], // Vue 推荐规则
  ...pluginVue.configs['flat/strongly-recommended'], // Vue 强烈推荐规则
  unocss,
  // languageOptions：配置如何检查 js 代码
  {
    // 1.1 处理 与 JavaScript 相关的配置项
    ignores: ['**/*.config.[m]js', 'dist/**', 'node_modules/**', '!**/eslint.config.mts'],
    languageOptions: {
      // 1.11 定义可用的全局变量
      globals: {
        ...globals.node,
        ...globals.browser,
        ...autoImportGlobals.globals,
      },
      // 1.12 扩展
      parserOptions: {
        parser: '@typescript-eslint/parser',
        extraFileExtensions: ['.vue'],
        ecmaVersion: 'latest',
        sourceType: 'module',
      },
    },
  },
  {
    plugins: { prettier, import: importPlugin, unusedImports, unicorn, perfectionist },
    rules: {
      // ----------------------  prettier  ----------------------
      'prettier/prettier': 'warn',

      // eslint（https://eslint.org/docs/latest/rules）
      'no-var': 'error', // 要求使用 let 或 const 而不是 var
      'no-undef': 'off', // 允许使用未定义的变量
      'no-unused-vars': 'off',
      'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
      'no-console': 'off',
      'no-debugger': 'off',
      'no-unexpected-multiline': 'error', // 禁止空余的多行
      'no-useless-escape': 'off', // 禁止不必要的转义字符,
      'padding-line-between-statements': [
        'error',
        { blankLine: 'always', prev: 'function', next: 'function' }, // 在函数和函数之间添加空行
        { blankLine: 'always', prev: 'function', next: 'expression' }, // 在函数和表达式之间添加空行
        { blankLine: 'always', prev: 'expression', next: 'function' }, // 在表达式和函数之间添加空行
        { blankLine: 'always', prev: 'block-like', next: 'block-like' }, // 在块级语句之间添加空行
      ],

      // js/ts
      camelcase: ['error', { properties: 'never' }],
      'no-constant-condition': ['error', { checkLoops: false }],
      'no-restricted-syntax': ['error', 'LabeledStatement', 'WithStatement'],
      'no-return-await': 'error',
      'no-empty': ['error', { allowEmptyCatch: true }],
      'prefer-const': ['warn', { destructuring: 'all', ignoreReadBeforeAssign: true }],
      'prefer-arrow-callback': ['error', { allowNamedFunctions: false, allowUnboundThis: true }],
      'object-shorthand': ['error', 'always', { ignoreConstructors: false, avoidQuotes: true }],
      'prefer-rest-params': 'error',
      'prefer-spread': 'error',
      'prefer-template': 'error',

      'no-redeclare': 'off',

      // best-practice
      'array-callback-return': 'error',
      'block-scoped-var': 'error',
      'no-alert': 'warn',
      'no-case-declarations': 'error',
      'no-multi-str': 'error',
      'no-with': 'error',
      'no-void': 'error',

      // typeScript (https://typescript-eslint.io/rules)
      '@typescript-eslint/no-unused-vars': [
        'warn',
        {
          argsIgnorePattern: '^_', // 忽略 _ 开头的参数
          caughtErrors: 'all', // 忽略所有错误
          caughtErrorsIgnorePattern: '^_', // 忽略 _ 开头的错误
          varsIgnorePattern: '^_', // 忽略 _ 开头的变量
          ignoreRestSiblings: true, // 忽略剩余参数
        },
      ], // 禁止定义未使用的变量
      '@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
      '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
      '@typescript-eslint/no-non-null-assertion': 'off',
      '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
      '@typescript-eslint/semi': 'off',
      // 允许 isShowToast && ElMessage.success('删除成功') 这种写法
      '@typescript-eslint/ban-ts-comment': 'off',
      '@typescript-eslint/no-unused-expressions': 'off',
      '@typescript-eslint/explicit-module-boundary-types': 'off',
      '@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
      '@typescript-eslint/no-require-imports': 'off',
      '@typescript-eslint/no-redeclare': 'error',
      '@typescript-eslint/consistent-type-imports': [
        'error',
        {
          disallowTypeAnnotations: false,
          fixStyle: 'separate-type-imports',
          prefer: 'type-imports',
        },
      ],

      // eslint-plugin-vue (https://eslint.vuejs.org/rules/)
      'vue/multi-word-component-names': 'off', // 要求组件名称始终为 "-" 链接的单词
      'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
      'vue/attribute-hyphenation': 'error', // 对模板中的自定义组件强制执行属性命名样式
      'vue/attributes-order': 'error', // 强制属性顺序
      'vue/padding-line-between-blocks': 'error', // 强制块之间的间距
      'vue/no-empty-component-block': 'error', // 禁止空的组件块报错
      // ✅ 强制 template > script > style
      'vue/block-order': ['error', { order: ['template', 'script', 'style'] }],
      // ✅ 强制单行属性
      'vue/max-attributes-per-line': 'off',
      'vue/singleline-html-element-content-newline': 'off',
      'vue/html-indent': 'off',
      'vue/one-component-per-file': 'off',
      'vue/component-definition-name-casing': 'off',
      'vue/no-v-html': 'off',
      'vue/require-default-prop': 'off',
      'vue/require-explicit-emits': 'off',
      'vue/prefer-import-from-vue': 'off',
      'vue/no-v-text-v-html-on-component': 'off',
      // 强制单标签格式
      'vue/html-self-closing': [
        'error',
        {
          html: {
            void: 'always', // 对于 void 元素使用单标签格式
            normal: 'never', // 非 void 元素不允许使用单标签格式
            component: 'always', // 自定义组件总是使用单标签格式
          },
          svg: 'always', // 对于 SVG 元素使用单标签格式
          math: 'always', // 对于 MathML 元素使用单标签格式
        },
      ],

      // unocss (https://unocss.dev/config/rules)
      // 'unocss/order-attributify': 'error', // 强制unocss属性顺序

      // eslint-plugin-unicorn (https://github.com/sindresorhus/eslint-plugin-unicorn)
      'unicorn/custom-error-definition': 'error',
      'unicorn/error-message': 'error',
      'unicorn/escape-case': 'error',
      'unicorn/new-for-builtins': 'error',
      'unicorn/no-array-method-this-argument': 'error',
      'unicorn/no-array-push-push': 'error',
      'unicorn/no-console-spaces': 'error',
      'unicorn/no-for-loop': 'error',
      'unicorn/no-hex-escape': 'error',
      'unicorn/no-instanceof-array': 'error',
      'unicorn/no-invalid-remove-event-listener': 'error',
      'unicorn/no-new-array': 'error',
      'unicorn/no-new-buffer': 'error',
      'unicorn/no-unsafe-regex': 'off',
      'unicorn/number-literal-case': 'error',
      'unicorn/prefer-array-find': 'error',
      'unicorn/prefer-array-flat-map': 'error',
      'unicorn/prefer-array-index-of': 'error',
      'unicorn/prefer-array-some': 'error',
      'unicorn/prefer-date-now': 'error',
      'unicorn/prefer-dom-node-dataset': 'error',
      'unicorn/prefer-includes': 'error',
      'unicorn/prefer-keyboard-event-key': 'error',
      'unicorn/prefer-math-trunc': 'error',
      'unicorn/prefer-modern-dom-apis': 'error',
      'unicorn/prefer-negative-index': 'error',
      'unicorn/prefer-number-properties': 'error',
      'unicorn/prefer-optional-catch-binding': 'error',
      'unicorn/prefer-prototype-methods': 'error',
      'unicorn/prefer-query-selector': 'error',
      'unicorn/prefer-reflect-apply': 'error',
      'unicorn/prefer-string-slice': 'error',
      'unicorn/prefer-string-starts-ends-with': 'error',
      'unicorn/prefer-string-trim-start-end': 'error',
      'unicorn/prefer-type-error': 'error',
      'unicorn/throw-new-error': 'error',

      // eslint-plugin-import (https://github.com/import-js/eslint-plugin-import)
      'import/newline-after-import': ['error', { count: 1 }], // 在 import 语句后需要换行
      'import/no-duplicates': 'error',

      // eslint-plugin-perfectionist (https://github.com/azat-io/eslint-plugin-perfectionist)
      'perfectionist/sort-exports': ['error', { order: 'asc', type: 'natural' }],
      'perfectionist/sort-imports': [
        'error',
        {
          groups: [
            'type',
            ['parent-type', 'sibling-type', 'index-type', 'internal-type'],

            'builtin',
            'external',
            'internal',
            ['parent', 'sibling', 'index'],
            'side-effect',
            'object',
            'unknown',
          ],
          newlinesBetween: 'ignore',
          order: 'asc',
          type: 'natural',
        },
      ],
      'perfectionist/sort-named-exports': ['error', { order: 'asc', type: 'natural' }],
      'perfectionist/sort-named-imports': ['error', { order: 'asc', type: 'natural' }],

      // eslint-plugin-unused-imports (https://github.com/sweepline/eslint-plugin-unused-imports)
      'unusedImports/no-unused-imports': 'warn', // 自动移除import中未使用的变量和参数
    },
  },
  {
    plugins: { jsdoc },
    files: ['src/**/*.{ts,js,vue}'],
    rules: {
      'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
      'jsdoc/check-tag-names': ['warn', { definedTags: ['value'] }],
      'jsdoc/check-param-names': 'warn',
      'jsdoc/check-types': 'warn',
      'jsdoc/require-param': 'warn',
      'jsdoc/require-returns': 'off',
      'jsdoc/require-description': 'warn',
    },
  },
]
